package com.ruoyi.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.app.domain.AppDynamic;
import com.ruoyi.app.domain.AppDynamicVideo;
import com.ruoyi.app.domain.AppFriend;
import com.ruoyi.app.domain.bo.AppDynamicBo;
import com.ruoyi.app.domain.bo.AppDynamicCommentBo;
import com.ruoyi.app.domain.bo.AppDynamicVideoBo;
import com.ruoyi.app.domain.bo.AppLikeNotesBo;
import com.ruoyi.app.domain.vo.*;
import com.ruoyi.app.mapper.AppDynamicMapper;
import com.ruoyi.app.mapper.AppDynamicTypeMapper;
import com.ruoyi.app.mapper.AppDynamicVideoMapper;
import com.ruoyi.app.mapper.AppFriendMapper;
import com.ruoyi.app.service.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.CommentType;
import com.ruoyi.common.enums.DynamicType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * APP用户动态Service业务层处理
 *
 * @author heike
 * @date 2025-12-22
 */
@RequiredArgsConstructor
@Service
public class AppDynamicServiceImpl implements IAppDynamicService {

    private final AppDynamicMapper baseMapper;
    private final IAppUserService appUserService;
    private final AppFriendMapper appFriendMapper;
    private final AppDynamicVideoMapper appDynamicVideoMapper;
    private final AppDynamicTypeMapper appDynamicTypeMapper;
    private final IAppDynamicLikeService appDynamicLikeService;
    private final IAppLikeNotesService appLikeNotesService;
    private final IAppDynamicVideoService appDynamicVideoService;
    private final IAppDynamicCommentService appDynamicCommentService;

    /**
     * 查询APP用户动态
     */
    @Override
    public AppDynamicVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    @Override
    public AppDynamicVo selectLimitOne(LambdaQueryWrapper<AppDynamic> queryWrapper) {
        return baseMapper.selectVoOne(queryWrapper);
    }

    /**
     * 查询APP用户动态列表
     */
    @Override
    public TableDataInfo<AppDynamicVo> queryPageList(AppDynamicBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<AppDynamic> lqw = buildQueryWrapper(bo);
        lqw.orderByDesc(AppDynamic::getCreateTime);
        Page<AppDynamicVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询APP用户动态列表
     */
    @Override
    public TableDataInfo<AppDynamicVo> queryPageList(Long id, String type, PageQuery pageQuery) {
        LambdaQueryWrapper<AppDynamic> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(AppDynamic::getDynamicType, "," + id + ",");
        if (!StringUtils.equals(type, Constants.SUCCESS)) {
            wrapper.orderByDesc(AppDynamic::getCreateTime);
        }
        Page<AppDynamicVo> result = baseMapper.selectVoPage(pageQuery.build(), wrapper);
        return TableDataInfo.build(result);
    }

    /**
     * 查询APP用户动态列表
     */
    @Override
    public List<AppDynamicVo> queryPageList(Long id, String type) {
        LambdaQueryWrapper<AppDynamic> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AppDynamic::getDynamicType,  id);
        return baseMapper.selectVoList(wrapper);
    }

    /**
     * 查询APP用户动态列表
     */
    @Override
    public List<AppDynamicVo> queryList(AppDynamicBo bo) {
        LambdaQueryWrapper<AppDynamic> lqw = buildQueryWrapper(bo);
        lqw.orderByDesc(AppDynamic::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<AppDynamic> buildQueryWrapper(AppDynamicBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<AppDynamic> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, AppDynamic::getUserId, bo.getUserId());
        lqw.like(StringUtils.isNotBlank(bo.getContext()), AppDynamic::getContext, bo.getContext());
        lqw.eq(StringUtils.isNotBlank(bo.getImages()), AppDynamic::getImages, bo.getImages());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), AppDynamic::getAddress, bo.getAddress());
        lqw.eq(bo.getLongitude() != null, AppDynamic::getLongitude, bo.getLongitude());
        lqw.eq(bo.getLatitude() != null, AppDynamic::getLatitude, bo.getLatitude());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), AppDynamic::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getScope()), AppDynamic::getScope, bo.getScope());
        lqw.eq(StringUtils.isNotBlank(bo.getDynamicType()), AppDynamic::getDynamicType, bo.getDynamicType());
        return lqw;
    }

    /**
     * 新增APP用户动态
     */
    @Override
    public Boolean insertByBo(AppDynamicBo bo) {
        AppDynamic add = BeanUtil.toBean(bo, AppDynamic.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addDynamic(AppDynamicBo bo) {
        if (insertByBo(bo)) {
            if (bo.getType().equals(DynamicType.VIDEO.getCode())) {
                AppDynamicVideo video = new AppDynamicVideo();
                video.setUrl(bo.getUrl());
                video.setImage(bo.getImages());
                video.setDynamicId(bo.getId());
                appDynamicVideoMapper.insert(video);
            } else {
                for (int i = 0; i < bo.getImagesList().size(); i++) {
                    String e = bo.getImagesList().get(i);
                    AppDynamicVideo video = new AppDynamicVideo();
                    video.setImage(e);
                    video.setDynamicId(bo.getId());
                    video.setSmallImage(e);
                    appDynamicVideoMapper.insert(video);
                }

            }
            return true;
        }
        return false;
    }

    /**
     * 修改APP用户动态
     */
    @Override
    public Boolean updateByBo(AppDynamicBo bo) {
        AppDynamic update = BeanUtil.toBean(bo, AppDynamic.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AppDynamic entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除APP用户动态
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean delete(Long id) {
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    public TableDataInfo<AppDynamicVo> queryDate(TableDataInfo<AppDynamicVo> page, Long id) {
        for (AppDynamicVo e : page.getData()) {
            info(e, id);
        }
        return page;
    }

    @Override
    public List<AppDynamicVo> queryDate(List<AppDynamicVo> list, Long id) {
        for (AppDynamicVo e : list) {
            info(e, id);
        }
        return list;
    }

    @Override
    public AppDynamicVo findOne(Long id, Long userId) {
        return info(queryById(id), userId);
    }

    /**
     * 处理动态信息
     *
     * @param e  动态信息
     * @param id 用户ID
     * @return
     */
    public AppDynamicVo info(AppDynamicVo e, Long id) {
        List<AppDynamicLikeVo> likeVos = appDynamicLikeService.queryByLike(e.getId(), CommentType.DYNAMIC.getCode());
        //点赞人列表点赞数量
        if (likeVos.size() > 0) {
            likeVos.forEach(i -> i.setUserVo(appUserService.userVo(i.getUserId())));
        }
        e.setLikeVos(likeVos);
        e.setLikeVosNumber(likeVos.size());
        //当前用户是否点赞
        e.setUserLike(appDynamicLikeService.queryByUser(e.getId(), id, CommentType.DYNAMIC.getCode()));
        //收藏数量
        AppLikeNotesBo appLikeNotes = new AppLikeNotesBo();
        appLikeNotes.setSideId(e.getId());
        appLikeNotes.setStatus(Constants.SUCCESS);
        List<AppLikeNotesVo> appLikeNotesVos = appLikeNotesService.queryList(appLikeNotes);
        e.setCollectVosNumber(appLikeNotesVos.size());
        //当前用户是否收藏
        appLikeNotes.setUserId(id);
        e.setCollectLike(!appLikeNotesService.queryList(appLikeNotes).isEmpty());
        //评论信息
        AppDynamicCommentBo commentBo = new AppDynamicCommentBo();
        commentBo.setDynamicId(e.getId());
        List<AppDynamicCommentVo> commentVos = appDynamicCommentService.queryList(commentBo);
        if (commentVos.size() > 0) {
            e.setCommentVosNumber(commentVos.size());
            commentVos.forEach(c -> {
                c.setUserVo(appUserService.queryById(c.getUserId()));
                List<AppDynamicLikeVo> commentLikes = appDynamicLikeService.queryByLike(c.getId(), CommentType.COMMENT.getCode());
                if (commentLikes.size() > 0) {
                    c.setCommentLikeVosNumber(commentLikes.size());
                }
                c.setUserCommentLike(appDynamicLikeService.queryByUser(c.getId(), id, CommentType.COMMENT.getCode()));
                c.setCreateTimeFormat(DateUtils.getDatePoorSingle(c.getCreateTime()));
            });
            e.setCommentVos(commentVos);
        } else {
            e.setCommentVos(commentVos);
            e.setCommentVosNumber(0);
        }
        //发布动态用户信息
        UserResultVo userVo = appUserService.filterateUserVo(e.getUserId());
        //用户关系
        if (!id.equals(e.getUserId())) {
            userVo.setIsRelation(Constants.STRANG);
            AppFriendVo appFriendVo = appFriendMapper.selectVoOne(
                new LambdaQueryWrapper<AppFriend>()
                    .eq(AppFriend::getUserId, id)
                    .eq(AppFriend::getFriendId, e.getUserId())
            );
            if (Objects.nonNull(appFriendVo)) {
                //如果对方关注了当前用户,则为好友
                AppFriendVo friendVo = appFriendMapper.selectVoOne(
                    new LambdaQueryWrapper<AppFriend>()
                        .eq(AppFriend::getUserId, e.getUserId())
                        .eq(AppFriend::getFriendId, id)
                );
                if (Objects.nonNull(friendVo)) {
                    userVo.setIsRelation(Constants.TWO);
                } else {
                    userVo.setIsRelation(Constants.LIKE);
                }
            }
        }
        e.setUserVo(userVo);
        //动态图片和视频信息
        AppDynamicVideoBo appDynamicVideoBo = new AppDynamicVideoBo();
        appDynamicVideoBo.setDynamicId(e.getId());
        List<AppDynamicVideoVo> videoVos = appDynamicVideoService.queryList(appDynamicVideoBo);
        e.setVideoVos(videoVos);
        String createTimeFormat = DateUtils.getDatePoorSingle(e.getCreateTime());
        if (createTimeFormat == null) {
            createTimeFormat = Constants.JUST;
        }
        e.setCreateTimeFormat(createTimeFormat);
        //兴趣爱好信息列表
        if (StringUtils.isNotBlank(e.getDynamicType())) {
            String[] split = e.getDynamicType().split(",");
            ArrayList<AppDynamicTypeVo> typeVos = new ArrayList<>();
            for (String s : split) {
                if (StringUtils.isBlank(s)) {
                    continue;
                }
                AppDynamicTypeVo type = appDynamicTypeMapper.selectVoById(Long.valueOf(s));
                if (Objects.nonNull(type)) {
                    typeVos.add(type);
                }
            }
            e.setDynamicTypeList(typeVos);
        }
        //获取@用户的列表
        if (StringUtils.isNotBlank(e.getIds())) {
            String[] split = e.getIds().split(",");
            ArrayList<UserResultVo> userVos = new ArrayList<>();
            for (String s : split) {
                if (StringUtils.isBlank(s)) {
                    continue;
                }
                UserResultVo resultVo = appUserService.filterateUserVo(Long.valueOf(s));
                if (Objects.nonNull(resultVo)) {
                    userVos.add(resultVo);
                }
            }
            e.setUserResultList(userVos);
        }
        return e;
    }


    @Override
    public AppDynamicVo findOne(Long id) {
        AppDynamicVo e = queryById(id);
        List<AppDynamicLikeVo> likeVos = appDynamicLikeService.queryByLike(e.getId(), CommentType.DYNAMIC.getCode());
        //点赞人列表点赞数量
        if (likeVos.size() > 0) {
            likeVos.forEach(i -> i.setUserVo(appUserService.userVo(i.getUserId())));
        }
        e.setLikeVos(likeVos);
        e.setLikeVosNumber(likeVos.size());
        //评论信息
        AppDynamicCommentBo commentBo = new AppDynamicCommentBo();
        commentBo.setDynamicId(e.getId());
        List<AppDynamicCommentVo> commentVos = appDynamicCommentService.queryList(commentBo);
        if (commentVos.size() > 0) {
            e.setCommentVosNumber(commentVos.size());
            commentVos.forEach(c -> {
                c.setUserVo(appUserService.queryById(c.getUserId()));
                List<AppDynamicLikeVo> commentLikes = appDynamicLikeService.queryByLike(c.getId(), CommentType.COMMENT.getCode());
                if (commentLikes.size() > 0) {
                    c.setCommentLikeVosNumber(commentLikes.size());
                }
                c.setCreateTimeFormat(DateUtils.getDatePoorSingle(c.getCreateTime()));
            });
            e.setCommentVos(commentVos);
        } else {
            e.setCommentVos(null);
            e.setCommentVosNumber(0);
        }
        //发布动态用户信息
        e.setUserVo(appUserService.filterateUserVo(e.getUserId()));
        //动态图片和视频信息
        AppDynamicVideoBo appDynamicVideoBo = new AppDynamicVideoBo();
        appDynamicVideoBo.setDynamicId(e.getId());
        List<AppDynamicVideoVo> videoVos = appDynamicVideoService.queryList(appDynamicVideoBo);
        e.setVideoVos(videoVos);
        String createTimeFormat = DateUtils.getDatePoorSingle(e.getCreateTime());
        if (createTimeFormat == null) {
            createTimeFormat = Constants.JUST;
        }
        e.setCreateTimeFormat(createTimeFormat);
        return e;
    }
}
